<template>
  <el-dialog
    v-model="visible"
    title="人脸搜索 - 身份验证"
    width="900px"
    :before-close="handleClose"
    destroy-on-close
    class="face-search-modal"
  >
    <div class="search-modal">
      <!-- 用户信息展示 -->
      <div class="user-info-section">
        <h4>👤 当前用户信息</h4>
        <div v-if="isUserLoggedIn" class="user-info-card">
          <div class="user-avatar">
            <el-avatar 
              :size="50" 
              :src="currentUser.avatar" 
              :icon="User"
            />
          </div>
          <div class="user-details">
            <div class="user-name">
              <el-icon><User /></el-icon>
              <span>{{ currentUser.nickname || '未设置昵称' }}</span>
            </div>
            <div class="user-id">
              <span class="label">用户ID:</span>
              <el-tag type="primary" size="small">{{ currentUser.id }}</el-tag>
            </div>
            <div class="auth-status">
              <span class="label">认证状态:</span>
              <el-tag :type="isAuthenticated ? 'success' : 'warning'" size="small">
                {{ isAuthenticated ? '已认证' : '未认证' }}
              </el-tag>
            </div>
          </div>
        </div>
        <div v-else class="user-info-empty">
          <el-alert
            title="用户未登录"
            description="请先登录系统后再进行人脸搜索"
            type="warning"
            :closable="false"
            show-icon
          />
        </div>
      </div>

      <!-- 配置选择 -->
      <div class="config-section">
        <h4>⚙️ 搜索配置</h4>
        <el-form :model="searchForm" label-width="100px">
          <el-form-item label="配置选择" required>
            <el-select
              v-model="searchForm.configId"
              placeholder="请选择人脸识别配置"
              style="width: 100%"
              :loading="configLoading"
            >
              <el-option
                v-for="config in configList"
                :key="config.id"
                :label="config.name"
                :value="config.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="搜索范围">
            <el-select
              v-model="searchForm.groupId"
              placeholder="选择搜索范围（默认全库搜索）"
              style="width: 100%"
              clearable
            >
              <el-option label="全库搜索" value="" />
              <el-option label="当前用户组" :value="currentUser.id?.toString()" />
            </el-select>
          </el-form-item>
          <el-form-item label="相似度阈值">
            <el-slider
              v-model="searchForm.threshold"
              :min="0.6"
              :max="1.0"
              :step="0.01"
              :format-tooltip="formatThreshold"
              show-input
              :input-size="'small'"
            />
            <div class="threshold-tip">
              <span>建议值: 0.8以上为高相似度，0.7-0.8为中等相似度</span>
            </div>
          </el-form-item>
        </el-form>
      </div>

      <!-- 摄像头区域 -->
      <div class="camera-section">
        <h4>📷 人脸拍摄</h4>
        
        <!-- 安全检测控制 -->
        <div class="security-controls">
          <div class="control-item">
            <el-switch
              v-model="livenessDetection.isActive"
              active-text="活体检测"
              inactive-text="关闭活体检测"
              active-color="#13ce66"
              inactive-color="#ff4949"
            />
            <el-tooltip content="开启后需要眨眼验证，提高搜索安全性" placement="top">
              <el-icon class="info-icon"><QuestionFilled /></el-icon>
            </el-tooltip>
          </div>
          
          <div v-if="livenessDetection.isActive" class="liveness-status">
            <span class="status-text">眨眼进度:</span>
            <el-progress
              :percentage="(livenessDetection.blinkCount / livenessDetection.requiredBlinks) * 100"
              :stroke-width="8"
              :show-text="false"
              status="success"
            />
            <span class="blink-count">{{ livenessDetection.blinkCount }}/{{ livenessDetection.requiredBlinks }}</span>
          </div>
        </div>
        
        <div class="camera-container">
          <div class="camera-preview">
            <!-- 摄像头状态指示器 -->
            <div :class="['camera-status', cameraActive ? 'active' : 'inactive']">
              <div class="camera-status-dot"></div>
              {{ cameraActive ? '摄像头已开启 - 请保持人脸在画面中央' : '摄像头已关闭' }}
            </div>
            
            <!-- 质量检测提示 -->
            <div v-if="cameraActive" class="quality-tips">
              <div class="tip-item">
                <el-icon><Sunny /></el-icon>
                <span>确保光线充足</span>
              </div>
              <div class="tip-item">
                <el-icon><View /></el-icon>
                <span>保持人脸清晰</span>
              </div>
              <div class="tip-item">
                <el-icon><Position /></el-icon>
                <span>正对摄像头</span>
              </div>
            </div>
            
            <!-- 人脸检测框 -->
            <div v-if="cameraActive" class="face-detection-guide">
              <div class="face-frame">
                <div class="corner top-left"></div>
                <div class="corner top-right"></div>
                <div class="corner bottom-left"></div>
                <div class="corner bottom-right"></div>
                <div class="face-guide-text">
                  {{ livenessDetection.isActive ? '请将人脸对准此区域并眨眼' : '请将人脸对准此区域' }}
                </div>
              </div>
            </div>
            
            <video
              ref="videoRef"
              v-show="cameraActive"
              autoplay
              playsinline
              class="camera-video"
            ></video>
            <canvas
              ref="canvasRef"
              v-show="false"
              class="camera-canvas"
            ></canvas>
            
            <!-- 拍摄的照片预览 -->
            <div v-if="capturedImageUrl && !cameraActive" class="captured-preview">
              <img :src="capturedImageUrl" alt="拍摄的照片" class="captured-image" />
              <div class="captured-overlay">
                <el-button type="primary" size="small" @click="startCamera">
                  <el-icon><VideoCamera /></el-icon>
                  重新拍照
                </el-button>
              </div>
            </div>
            
            <div v-if="!cameraActive && !capturedImageUrl" class="camera-placeholder">
              <el-icon size="48"><Camera /></el-icon>
              <p>点击开启摄像头开始人脸搜索</p>
              <p class="placeholder-tip">请确保光线充足，人脸清晰可见</p>
            </div>
          </div>
          
          <div class="camera-controls">
            <el-button
              v-if="!cameraActive"
              type="primary"
              @click="startCamera"
              :loading="cameraLoading"
            >
              <el-icon><VideoCamera /></el-icon>
              开启摄像头
            </el-button>
            <template v-else>
              <el-button
                type="success"
                @click="capturePhoto"
                :disabled="!cameraActive"
              >
                <el-icon><Camera /></el-icon>
                拍照
              </el-button>
              <el-button
                type="danger"
                @click="stopCamera"
              >
                <el-icon><Close /></el-icon>
                关闭摄像头
              </el-button>
            </template>
          </div>
        </div>
      </div>

      <!-- 搜索操作 -->
      <div class="action-section">
        <h4>🔍 人脸搜索</h4>
        <div class="action-description">
          <el-alert
            title="搜索说明"
            description="通过人脸搜索可以验证身份信息，确认是否为已注册用户"
            type="info"
            :closable="false"
            show-icon
          />
        </div>
        <div class="action-buttons">
          <el-button
            type="primary"
            size="large"
            @click="handleSearch"
            :disabled="!canSearch"
            :loading="searchLoading"
          >
            <el-icon><Search /></el-icon>
            开始人脸搜索
          </el-button>
        </div>
      </div>

      <!-- 搜索结果 -->
      <div class="result-section" v-if="searchResult">
        <h4>📊 搜索结果</h4>
        <div class="result-content">
          <div v-if="searchResult.success && searchResult.data.length > 0" class="result-success">
            <el-alert
              title="找到匹配结果"
              type="success"
              :closable="false"
              show-icon
            >
              <template #default>
                <div class="match-summary">
                  <span>共找到 {{ searchResult.data.length }} 个匹配结果</span>
                </div>
              </template>
            </el-alert>
            
            <!-- 匹配结果列表 -->
            <div class="match-results">
              <div 
                v-for="(match, index) in searchResult.data" 
                :key="index"
                class="match-item"
              >
                <div class="match-header">
                  <div class="match-rank">
                    <el-tag :type="getMatchType(match.score)" size="large">
                      #{{ index + 1 }}
                    </el-tag>
                  </div>
                  <div class="match-score">
                    <span class="score-label">相似度:</span>
                    <el-progress 
                      :percentage="Math.round(match.score * 100)" 
                      :color="getScoreColor(match.score)"
                      :stroke-width="8"
                    />
                    <span class="score-value">{{ (match.score * 100).toFixed(2) }}%</span>
                  </div>
                </div>
                <div class="match-details">
                  <div class="detail-item">
                    <span class="detail-label">用户ID:</span>
                    <el-tag type="primary">{{ match.userId }}</el-tag>
                  </div>
                  <div class="detail-item">
                    <span class="detail-label">人脸Token:</span>
                    <el-tag type="info">{{ match.faceToken?.substring(0, 16) }}...</el-tag>
                  </div>
                  <div v-if="match.groupId" class="detail-item">
                    <span class="detail-label">用户组:</span>
                    <el-tag type="warning">{{ match.groupId }}</el-tag>
                  </div>
                  <div class="detail-item">
                    <span class="detail-label">匹配状态:</span>
                    <el-tag :type="match.score >= searchForm.threshold ? 'success' : 'danger'">
                      {{ match.score >= searchForm.threshold ? '身份验证通过' : '相似度不足' }}
                    </el-tag>
                  </div>
                </div>
              </div>
            </div>
          </div>
          
          <div v-else-if="searchResult.success && searchResult.data.length === 0" class="result-empty">
            <el-alert
              title="未找到匹配结果"
              description="在数据库中未找到相似的人脸信息，可能需要先进行人脸注册"
              type="warning"
              :closable="false"
              show-icon
            />
          </div>
          
          <div v-else class="result-error">
            <el-alert
              title="搜索失败"
              :description="searchResult.message"
              type="error"
              :closable="false"
              show-icon
            />
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">关闭</el-button>
        <el-button type="primary" @click="clearResult" v-if="searchResult">
          清除结果
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { 
  Camera, 
  VideoCamera, 
  Close, 
  User, 
  Search,
  QuestionFilled,
  Sunny,
  View,
  Position
} from '@element-plus/icons-vue'
import { useUserStore } from '@/store/modules/user'
import {
  searchFaceBase64,
  type FaceSearchReqVO,
  type FaceSearchRespVO
} from '@/api/infra/face'

// Props
interface Props {
  modelValue: boolean
  configList: any[]
  configLoading: boolean
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  configList: () => [],
  configLoading: false
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  success: []
}>()

const message = useMessage()
const userStore = useUserStore()

// 弹窗显示状态
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

// 当前登录用户信息
const currentUser = computed(() => userStore.getUser)
const isUserLoggedIn = computed(() => userStore.getIsSetUser && currentUser.value.id > 0)
const isAuthenticated = computed(() => currentUser.value?.faceToken ? true : false) // 基于faceToken判断认证状态

// 搜索表单
const searchForm = ref({
  configId: undefined,
  groupId: '',
  threshold: 0.8
})

// 摄像头相关
const videoRef = ref<HTMLVideoElement>()
const canvasRef = ref<HTMLCanvasElement>()
const cameraActive = ref(false)
const cameraLoading = ref(false)
const mediaStream = ref<MediaStream | null>(null)
const capturedImageUrl = ref('')
const capturedImageBase64 = ref('')

// 搜索相关
const searchLoading = ref(false)
const searchResult = ref<{ success: boolean; data?: any[]; message?: string } | null>(null)

// 活体检测相关
const livenessDetection = ref({
  isActive: false,
  blinkCount: 0,
  requiredBlinks: 3,
  isDetecting: false,
  lastEyeState: null as boolean | null
})

// 计算属性
const canSearch = computed(() => {
  return searchForm.value.configId && capturedImageBase64.value && isUserLoggedIn.value
})

// 格式化阈值显示
const formatThreshold = (value: number) => {
  return `${(value * 100).toFixed(0)}%`
}

// 获取匹配类型
const getMatchType = (score: number) => {
  if (score >= 0.9) return 'success'
  if (score >= 0.8) return 'warning'
  return 'danger'
}

// 获取分数颜色
const getScoreColor = (score: number) => {
  if (score >= 0.9) return '#67c23a'
  if (score >= 0.8) return '#e6a23c'
  return '#f56c6c'
}

// 开启摄像头
const startCamera = async () => {
  try {
    cameraLoading.value = true
    const stream = await navigator.mediaDevices.getUserMedia({ 
      video: { 
        width: { ideal: 640 },
        height: { ideal: 480 },
        facingMode: 'user'
      } 
    })
    
    if (videoRef.value) {
      videoRef.value.srcObject = stream
      mediaStream.value = stream
      cameraActive.value = true
      capturedImageUrl.value = ''
      capturedImageBase64.value = ''
    }
  } catch (error) {
    console.error('开启摄像头失败:', error)
    message.error('无法访问摄像头，请检查设备权限')
  } finally {
    cameraLoading.value = false
  }
}

// 关闭摄像头
const stopCamera = () => {
  if (mediaStream.value) {
    mediaStream.value.getTracks().forEach(track => track.stop())
    mediaStream.value = null
  }
  cameraActive.value = false
}

// 人脸质量检测
const checkFaceQuality = (imageData: ImageData) => {
  const { data, width, height } = imageData
  
  // 计算亮度
  let totalBrightness = 0
  for (let i = 0; i < data.length; i += 4) {
    const r = data[i]
    const g = data[i + 1]
    const b = data[i + 2]
    totalBrightness += (r + g + b) / 3
  }
  const avgBrightness = totalBrightness / (width * height)
  
  // 计算清晰度（基于边缘检测）
  let edgeStrength = 0
  for (let y = 1; y < height - 1; y++) {
    for (let x = 1; x < width - 1; x++) {
      const idx = (y * width + x) * 4
      const current = (data[idx] + data[idx + 1] + data[idx + 2]) / 3
      const right = (data[idx + 4] + data[idx + 5] + data[idx + 6]) / 3
      const bottom = (data[idx + width * 4] + data[idx + width * 4 + 1] + data[idx + width * 4 + 2]) / 3
      edgeStrength += Math.abs(current - right) + Math.abs(current - bottom)
    }
  }
  const avgEdgeStrength = edgeStrength / ((width - 2) * (height - 2))
  
  return {
    brightness: avgBrightness,
    sharpness: avgEdgeStrength,
    isGoodQuality: avgBrightness > 50 && avgBrightness < 200 && avgEdgeStrength > 10
  }
}

// 简单的眨眼检测
const detectBlink = (imageData: ImageData) => {
  // 这里实现简单的眨眼检测逻辑
  // 实际项目中应该使用更专业的人脸识别库
  const quality = checkFaceQuality(imageData)
  
  // 模拟眨眼检测：基于图像变化
  const currentEyeState = quality.brightness > 100 // 简化的眼部状态检测
  
  if (livenessDetection.value.lastEyeState !== null && 
      livenessDetection.value.lastEyeState !== currentEyeState && 
      !currentEyeState) {
    livenessDetection.value.blinkCount++
  }
  
  livenessDetection.value.lastEyeState = currentEyeState
  return currentEyeState
}

// 拍照
const capturePhoto = async () => {
  if (!videoRef.value || !canvasRef.value) return
  
  const video = videoRef.value
  const canvas = canvasRef.value
  const ctx = canvas.getContext('2d')
  
  if (!ctx) return
  
  // 设置画布尺寸
  canvas.width = video.videoWidth
  canvas.height = video.videoHeight
  
  // 绘制视频帧到画布
  ctx.drawImage(video, 0, 0)
  
  // 获取图像数据进行质量检测
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
  const quality = checkFaceQuality(imageData)
  
  // 检查图像质量
  if (!quality.isGoodQuality) {
    if (quality.brightness < 50) {
      message.warning('光线太暗，请调整光线后重试')
      return
    } else if (quality.brightness > 200) {
      message.warning('光线太亮，请调整光线后重试')
      return
    } else if (quality.sharpness < 10) {
      message.warning('图像不够清晰，请保持稳定后重试')
      return
    }
  }
  
  // 活体检测
  if (livenessDetection.value.isActive) {
    detectBlink(imageData)
    
    if (livenessDetection.value.blinkCount < livenessDetection.value.requiredBlinks) {
      message.warning(`请继续眨眼，还需要 ${livenessDetection.value.requiredBlinks - livenessDetection.value.blinkCount} 次`)
      return
    }
  }
  
  // 获取图片数据
  capturedImageUrl.value = canvas.toDataURL('image/jpeg', 0.8)
  capturedImageBase64.value = capturedImageUrl.value.split(',')[1]
  
  // 关闭摄像头
  stopCamera()
  
  message.success('照片拍摄成功，质量检测通过')
}

// 处理人脸搜索
const handleSearch = async () => {
  if (!canSearch.value) {
    message.warning('请先完成人脸拍摄')
    return
  }
  
  try {
    searchLoading.value = true
    
    const requestData: FaceSearchReqVO = {
      configId: searchForm.value.configId!,
      groupId: searchForm.value.groupId || undefined,
      image: capturedImageBase64.value,
      maxUserNum: 10, // 最多返回10个结果
      threshold: searchForm.value.threshold
    }
    
    const response = await searchFaceBase64(requestData)
    
    searchResult.value = {
      success: true,
      data: response.userList || []
    }
    
    if (response.userList && response.userList.length > 0) {
      const bestMatch = response.userList[0]
      if (bestMatch.score >= searchForm.value.threshold) {
        message.success(`身份验证成功，相似度: ${(bestMatch.score * 100).toFixed(2)}%`)
      } else {
        message.warning('相似度不足，身份验证失败')
      }
    } else {
      message.info('未找到匹配的人脸信息')
    }
    
    emit('success')
    
  } catch (error: any) {
    console.error('人脸搜索失败:', error)
    searchResult.value = {
      success: false,
      message: error.message || '搜索失败，请重试'
    }
    message.error('人脸搜索失败')
  } finally {
    searchLoading.value = false
  }
}

// 清除结果
const clearResult = () => {
  searchResult.value = null
  capturedImageUrl.value = ''
  capturedImageBase64.value = ''
}

// 关闭弹窗
const handleClose = () => {
  stopCamera()
  clearResult()
  visible.value = false
}

// 监听弹窗显示状态
watch(visible, (newVal) => {
  if (newVal && isUserLoggedIn.value) {
    // 自动选择第一个配置
    if (props.configList.length > 0) {
      searchForm.value.configId = props.configList[0].id
    }
  }
})

// 组件卸载时清理资源
onUnmounted(() => {
  stopCamera()
})
</script>

<style scoped>
.face-search-modal {
  --el-dialog-border-radius: 16px;
}

.search-modal {
  padding: 8px;
}

/* 用户信息区域 */
.user-info-section {
  margin-bottom: 24px;
}

.user-info-section h4 {
  margin-bottom: 16px;
  color: #303133;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.user-info-card {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 16px;
  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.2);
  color: white;
  transition: all 0.3s ease;
}

.user-info-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 32px rgba(102, 126, 234, 0.3);
}

.user-details {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.user-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  color: white;
}

.user-id, .auth-status {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}

.user-id .label, .auth-status .label {
  color: rgba(255, 255, 255, 0.8);
  font-weight: 500;
}

/* 配置区域 */
.config-section {
  margin-bottom: 24px;
}

.config-section h4 {
  margin-bottom: 16px;
  color: #303133;
  font-weight: 600;
}

.threshold-tip {
  margin-top: 8px;
  font-size: 12px;
  color: #909399;
}

/* 摄像头区域 */
.camera-section {
  margin-bottom: 24px;
}

.camera-section h4 {
  margin-bottom: 16px;
  color: #303133;
  font-weight: 600;
}

/* 安全检测控制 */
.security-controls {
  margin-bottom: 16px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e9ecef;
}

.control-item {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}

.info-icon {
  color: #909399;
  cursor: help;
}

.liveness-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: #e8f5e8;
  border-radius: 6px;
  border: 1px solid #b3d8b3;
}

.status-text {
  font-size: 14px;
  color: #67c23a;
  font-weight: 500;
  min-width: 80px;
}

.blink-count {
  font-size: 14px;
  color: #67c23a;
  font-weight: 600;
  min-width: 30px;
}

/* 质量检测提示 */
.quality-tips {
  position: absolute;
  top: 12px;
  left: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 10;
}

.tip-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
}

.tip-item .el-icon {
  font-size: 14px;
  color: #67c23a;
}

.camera-container {
  border: 2px dashed #dcdfe6;
  border-radius: 12px;
  padding: 20px;
  background: #fafafa;
}

.camera-preview {
  position: relative;
  width: 100%;
  height: 360px;
  border-radius: 8px;
  overflow: hidden;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.camera-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.camera-placeholder {
  text-align: center;
  color: #909399;
}

.camera-placeholder .el-icon {
  color: #c0c4cc;
  margin-bottom: 12px;
}

.camera-placeholder p {
  margin: 8px 0;
  font-size: 16px;
}

.placeholder-tip {
  font-size: 14px;
  color: #c0c4cc;
}

.camera-status {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: rgba(0,0,0,0.7);
  color: white;
  border-radius: 16px;
  font-size: 12px;
  font-weight: 500;
  z-index: 10;
}

.camera-status.active {
  background: rgba(67, 160, 71, 0.9);
}

.camera-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}

/* 人脸检测引导框 */
.face-detection-guide {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 5;
}

.face-frame {
  position: relative;
  width: 200px;
  height: 240px;
  border: 2px solid rgba(255, 255, 255, 0.8);
  border-radius: 12px;
}

.corner {
  position: absolute;
  width: 20px;
  height: 20px;
  border: 3px solid #409eff;
}

.corner.top-left {
  top: -3px;
  left: -3px;
  border-right: none;
  border-bottom: none;
}

.corner.top-right {
  top: -3px;
  right: -3px;
  border-left: none;
  border-bottom: none;
}

.corner.bottom-left {
  bottom: -3px;
  left: -3px;
  border-right: none;
  border-top: none;
}

.corner.bottom-right {
  bottom: -3px;
  right: -3px;
  border-left: none;
  border-top: none;
}

.face-guide-text {
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  color: white;
  font-size: 14px;
  font-weight: 500;
  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
  white-space: nowrap;
}

.captured-preview {
  position: relative;
  width: 100%;
  height: 100%;
}

.captured-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.captured-overlay {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.camera-controls {
  margin-top: 16px;
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

.camera-controls .el-button {
  min-width: 120px;
  height: 40px;
  font-weight: 500;
  border-radius: 20px;
}

/* 操作区域 */
.action-section {
  margin-bottom: 24px;
}

.action-section h4 {
  margin-bottom: 16px;
  color: #303133;
  font-weight: 600;
}

.action-description {
  margin-bottom: 16px;
}

.action-buttons {
  display: flex;
  justify-content: center;
  gap: 16px;
}

.action-buttons .el-button {
  min-width: 160px;
  height: 48px;
  font-size: 16px;
  font-weight: 600;
  border-radius: 24px;
}

/* 结果区域 */
.result-section {
  margin-bottom: 24px;
}

.result-section h4 {
  margin-bottom: 16px;
  color: #303133;
  font-weight: 600;
}

.match-results {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.match-item {
  border: 1px solid #e4e7ed;
  border-radius: 12px;
  padding: 16px;
  background: #fff;
  transition: all 0.3s ease;
}

.match-item:hover {
  border-color: #409eff;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.1);
}

.match-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 12px;
}

.match-rank {
  flex-shrink: 0;
}

.match-score {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 12px;
}

.score-label {
  font-weight: 500;
  color: #606266;
  min-width: 60px;
}

.score-value {
  font-weight: 600;
  color: #303133;
  min-width: 60px;
  text-align: right;
}

.match-details {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}

.detail-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.detail-label {
  font-weight: 500;
  color: #606266;
  min-width: 80px;
}

.match-summary {
  font-weight: 500;
  color: #67c23a;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .user-info-card {
    flex-direction: column;
    text-align: center;
    gap: 16px;
  }
  
  .camera-preview {
    height: 280px;
  }
  
  .face-frame {
    width: 160px;
    height: 200px;
  }
  
  .match-header {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }
  
  .match-details {
    grid-template-columns: 1fr;
  }
}
</style>